package main

import (
	"context"
	"fmt"
	//"net/http"
	//_ "net/http/pprof" // 导入 pprof
	"os"
	"os/signal"
	"syscall"
	"time"

	"monitor.ilin.cc/config"
	"monitor.ilin.cc/internal/services/alert"
	"monitor.ilin.cc/internal/services/db"
	"monitor.ilin.cc/internal/services/market"

	"github.com/sirupsen/logrus"
	"golang.org/x/sync/errgroup"
)

var log = logrus.New()

func main() {
	//// 添加 pprof 监听
	//go func() {
	//	log.Println(http.ListenAndServe("0.0.0.0:6060", nil))
	//}()

	// 初始化日志
	initLogger()

	// 添加 recover 机制
	defer func() {
		if err := recover(); err != nil {
			log.Errorf("Program crashed with error: %v", err)
		}
	}()

	// 加载配置
	cfg, err := config.LoadConfig("config.yaml")
	if err != nil {
		log.Fatalf("Failed to load config: %v", err)
	}

	if err := validateConfig(cfg); err != nil {
		log.Errorf("Invalid configuration: %v", err)
		os.Exit(1)
	}

	// 初始化服务
	dbService, err := db.NewService(&cfg.Database)
	if err != nil {
		log.Fatalf("Failed to initialize database: %v", err)
	}
	defer dbService.Close()

	alertService := alert.NewWeComAlertService(&cfg.Alert)

	// 创建监控器
	var monitors []market.Monitor
	for _, sub := range cfg.Market.Subscriptions {
		monitor, err := market.NewPriceChangeMonitor(
			sub.InstID,
			&sub.Alerts.PriceChange,
			alertService,
		)
		if err != nil {
			log.Errorf("Failed to create monitor for %s: %v", sub.InstID, err)
			continue
		}
		monitors = append(monitors, monitor)
	}

	// 创建 context 用于管理生命周期
	ctx, cancel := context.WithCancel(context.Background())
	defer cancel()

	// 创建 errgroup 用于管理 goroutine
	g, ctx := errgroup.WithContext(ctx)

	// 创建采集器
	collector, err := market.NewCollector(
		&cfg.Market,
		&cfg.OKEx,
		dbService,
		alertService,
		monitors,
	)
	if err != nil {
		log.Errorf("Failed to initialize collector: %v", err)
		gracefulShutdown()
		os.Exit(1)
	}

	// 启动采集
	g.Go(func() error {
		if err := collector.Start(); err != nil {
			log.Errorf("Collector failed: %v", err)
			return err
		}
		return nil
	})

	// 信号处理
	g.Go(func() error {
		sigChan := make(chan os.Signal, 1)
		signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
		select {
		case sig := <-sigChan:
			log.Infof("Received signal: %v", sig)
			cancel()
		case <-ctx.Done():
		}
		return nil
	})

	// 等待所有 goroutine 完成
	if err := g.Wait(); err != nil {
		log.Errorf("Error during execution: %v", err)
	}
}

func initLogger() {
	log.SetFormatter(&logrus.JSONFormatter{})
	log.SetLevel(logrus.InfoLevel)
}

func validateConfig(cfg *config.Config) error {
	// 验证数据库配置
	if err := cfg.Database.Validate(); err != nil {
		return fmt.Errorf("database config: %v", err)
	}

	// 验证市场配置
	if err := cfg.Market.Validate(); err != nil {
		return fmt.Errorf("market config: %v", err)
	}

	// 验证告警配置
	if len(cfg.Alert.Channels) == 0 {
		return fmt.Errorf("no alert channels configured")
	}

	return nil
}

func gracefulShutdown() {
	log.Info("Starting graceful shutdown...")

	// 给一些时间让现有的操作完成
	time.Sleep(time.Second * 3)

	log.Info("Graceful shutdown completed")
}
